home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
viewers
/
hpglvu10
/
hpglview.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-04-18
|
33KB
|
999 lines
program HPGLVIEW;
{-----------------------------------------------------------------------------}
(* An HPGL viewer
The viewer takes a file of HPGL commands and displays the plot commands
on the screen.
It always represents the page (A3 or A4) lying sideways on the
screen, to preserve the maximum resolution, and ignores the aspect ratio
of the screen for the same reason.
Its designed to show you what the plot looks like on the page not be
an absolute mimic of a plot. If you need absolute precision, plot it.
-------------------------------------------------------------------------------
HPGLVIEW - a on-screen Previewer for HPGL files
Copyright (C) 1991 Giovanni S. Moretti
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-----------------------------------------------------------------------------
Giovanni Moretti | EMAIL: G.Moretti@massey.ac.nz
Computer Centre, Massey University |
Palmerston North, New Zealand |
-----------------------------------------------------------------------------
Please send me a copy of any major hacks/improvements so I can coordinate
any new releases.
HP-GL is (probably) a trademark of Hewlett-Packard Company.
*)
{-----------------------------------------------------------------------------}
{ RCS Control Information
$Author: Giovanni_Moretti $
$Date: 91/04/18 15:57:59 $
$Revision: 1.1 $
$Log: hpglview.pas $
Revision 1.1 91/04/18 15:57:59 ROOT_DOS
Initial revision
}
uses graph, dos, crt, smalfont, { Like FONTS.PAS with only SMALLFONT left}
drivers;
const A3_char_width = 0.285; {cm}
A3_char_height = 0.375;
A4_char_width = 0.187;
A4_char_height = 0.269;
unknown_max = 100;
var pen_down : boolean;
cmd : string; {Current HPGL command being done}
x, y, x1,y1 : real; {and the numeric arguments to this cmd}
lbl : string; {or a character string arg for LB cmd }
filename : string;
inf : text; {Input file}
screen_max_X : integer; {No of dots across screen -1}
screen_max_Y : integer; {and number down }
Graphics_Driver : integer; { for BGI - may be set manually with /G }
Graphics_mode : integer; { for BGI - may be set manually with /G }
{-----------------------------------------------------------------------------}
use_plotter_units : boolean; {If TRUE => NO Scaling, FALSE => Scale}
x_max : real; {Maximum and Minimum values as defined}
x_min : real; {by the SC (Scale) command }
y_max : real;
y_min : real;
x_p1, y_p1 : integer;
x_p2, y_p2 : integer;
{-----------------------------------------------------------------------------}
Paper_size : integer; {Either a 3 or 4 (A3 or A4) }
X_plot_area_mm : integer;
Y_plot_area_mm : integer;
args : boolean;
hard_clip_X : integer;
hard_clip_Y : integer;
colour : integer; {Current colour from video palette}
{-----------------------------------------------------------------------------}
char_height : real; {Currently set Character Height and Width}
char_width : real; {Always defined - used by SI and DI cmds }
text_direction : word; {Used by DI cmd }
{-----------------------------------------------------------------------------}
symbol_mode : boolean; {Whether a symbol is drawn on a PA or PR }
symbol_char : char; {command - used by the SM instruction }
{-----------------------------------------------------------------------------}
{Remember unimplemented commands in this array for later }
unknown_cmds : array [1..unknown_max] of string;
unknown_count : integer;
cnt : integer;
pause : char;
ch : char;
debug : boolean;
digits : set of char;
i : integer; {General Purpose Integer}
finished : boolean;
initialise_cmd_count : integer; {Used to pause on 2nd, 3rd ... IN cmd}
IP_cmd_count : integer; {Used to change colours on 2nd .. IP cmd}
auto_detect_graphics : boolean; {altered be /G command line option }
{-----------------------------------------------------------------------------}
procedure SET_DEFAULT_TEXT_DIRECTION;
begin
text_Direction:= HorizDir;
SetTextJustify(LeftText, BottomText);
end;
{-----------------------------------------------------------------------------}
{ Set up the appropriate scaling factors to draw text of the size defined by
HEIGHT and WIDTH.
HEIGHT and WIDTH are remembered in CHAR_HEIGHT and CHAR_WIDTH so
this procedure can be reused if TEXT_DIRECTION is redefined.
This procedure is used whenever it is necessary to change either
text size or direction.
}
procedure SET_TEXT_SIZE (width, height : real); {Arguments are in Centimetres}
var x_top, x_bottom, y_top, y_bottom : integer;
width_in_mm, height_in_mm : real;
scale_x, scale_y : real;
letter_height, letter_width : integer;
begin
{Scale ratios by 100 so as not to lose too much precision on ROUND()}
x_top:= 100; x_bottom:= 100; y_top:= 100; y_bottom:= 100;
{This Section Gives "Approximately" the correct size lettering }
SetTextStyle(SmallFont, HorizDir, 2);
letter_height:= TextHeight('M'); {Remember Size of Standard Characters}
letter_width := TextWidth('M');
width_in_mm := letter_width / screen_max_X * X_plot_area_mm;
scale_x:= (width*10) / width_in_mm; { *10 as SI args are in cm}
if scale_x > 10 then scale_x:= 10;
if scale_X > 1 then x_top := round(scale_x *100)
else x_bottom:= round(1/scale_X *100);
height_in_mm:= Letter_Height / screen_max_Y * Y_plot_area_mm;
scale_y:= (height*10) / height_in_mm; { *10 as SI args are in cm}
if scale_y > 10 then scale_y:= 10;
if scale_y > 1 then Y_top := round(scale_Y *100)
else Y_bottom:= round(1/scale_Y *100);
SetUserCharSize(x_top, x_bottom, y_top, y_bottom);
SetTextStyle(smallFont, text_direction, UserCharSize);
end;
{-----------------------------------------------------------------------------}
procedure SET_DEFAULT_TEXT_SIZE;
begin
if paper_size = 4 then { A4 Paper }
begin
char_height := A4_char_height;
char_width := A4_char_width;
end
else { A3 Paper }
begin
char_width := A3_char_width;
char_height := A3_char_height;
end;
set_text_size(char_width, char_height);
end;
{-----------------------------------------------------------------------------}
procedure SET_P1_P2 (x, y, x1, y1 : integer);
begin
x_p1:= x;
y_p1:= y;
x_p2:= x1;
y_p2:= y1;
end;
{-----------------------------------------------------------------------------}
procedure SET_DEFAULT_P1_P2;
begin
if paper_size = 4 then { A4 Paper }
begin
x_p2 := 10430;
x_p1 := 430;
y_p2 := 7400;
y_p1 := 200;
end
else { A3 Paper }
begin
x_p2 := 15580;
x_p1 := 380;
y_p2 := 10430;
y_p1 := 430;
end;
end;
{-----------------------------------------------------------------------------}
procedure SET_PAPER_SIZE ( default : integer);
begin
if default <> 0 then paper_size:= default
else
repeat
write('A4 or A3 paper (3/4) : ');
readln(paper_size);
until paper_size in [3,4];
if paper_size = 4 then
begin { A4 Paper }
X_plot_area_mm:= 270;
Y_plot_area_mm:= 190;
hard_clip_X := 10870;
hard_clip_Y := 7600;
end
else { A3 Paper }
begin
X_plot_area_mm:= 399;
Y_plot_area_mm:= 271;
hard_clip_X := 15970;
hard_clip_Y := 10870;
end;
end;
{-----------------------------------------------------------------------------}
{Search the list of already Unknown Commands to see if the current one has
already been added to the list
}
function SEEN_BEFORE (cmd : string) : boolean;
var i : integer;
found : boolean;
begin
i:= 0;
found:= false;
while (i < unknown_count) and not found do
begin
i:= i+1;
if unknown_cmds[i] = cmd then found:= true;
end;
seen_before:= found;
end;
{-----------------------------------------------------------------------------}
{ READARG - a version of READ-A-NUMBER that will handle numbers that start
with a decimal point (no leading digit)
On exit skip past any trailing terminators/separators
}
procedure READARG (var num: real);
label 99;
var seen_point : boolean;
divisor : integer;
is_negative: boolean;
begin
while not eof (inf) and not (ch in digits+['-']) do
read(inf, ch); {Just in Case}
if eof(inf) then goto 99;
num:= 0;
seen_point := false;
divisor := 1;
is_negative:= false;
if ch = '-' then begin is_negative:= true; read(inf, ch); end;
while ch in digits do
begin
if ch = '.' then seen_point:= true
else
begin
if seen_point then divisor:= divisor * 10;
num:= num*10 + (ord(ch)-ord('0'));
end;
read(inf, ch);
end;
if seen_point then num:= num / divisor;
if is_negative then num:= -num;
(* if ch in [',',';'] then read(inf, ch); {Skip past terminator/separator}*)
99:
end;
{-----------------------------------------------------------------------------}
{ GET THE NEXT HPGL COMMAND into "cmd" }
{ On EXIT: "cmd" - contains HPGL command }
procedure GET_CMD;
label 99;
begin
{ Skip past any non-alphabetic characters }
while not eof(inf) and not (ch in ['A'..'Z','a'..'z']) do
read(inf, ch); {Skip junk}
if eof(inf) then begin cmd:= 'ZZ'; goto 99; end;
cmd := '';
cmd:= concat(cmd, upcase(ch));
read(inf, ch);
if ch <> ';' then
begin
cmd:= concat(cmd, upcase(ch));
read(inf, ch);
end;
99:
end;
{-----------------------------------------------------------------------------}
procedure READ_OR_RESET_ARGS (num_of_args : integer);
begin
if ch = ';' then args:= false
else
begin
readarg(x);
if num_of_args >= 2 then readarg(y);
if num_of_args >= 3 then readarg(x1);
if num_of_args = 4 then readarg(y1);
args:= true;
end
end;
{-----------------------------------------------------------------------------}
{ SCALE THE PARAMETERS X & Y INTO SCREEN UNITS }
{If scaling is active the incoming values should be between:
X_min .. X_max which is scaled to fit between x_p1 .. x_p2 and ditto for Y
If not, then use plotter units and scale these to fit onto the screen
}
procedure SCALE (var x, y : integer);
begin
if use_plotter_units then
begin
x:= round( x/(hard_clip_X) * screen_max_X);
y:= screen_max_y - round( y/(hard_clip_y) * screen_max_Y);
end
else {Scaling is Active - Fit plot Using Coords P1 and P2 - defined in IP cmd}
begin
x:= round((((x-x_min)/(x_max-x_min)) * (x_p2-X_p1) + x_p1)/Hard_clip_X * Screen_max_X);
y:= round((((y-y_min)/(y_max-y_min)) * (y_p2-y_p1) + y_p1)/Hard_clip_Y * Screen_max_Y);
y:= screen_max_y - y;
end;
end;
{-----------------------------------------------------------------------------}
{PU - PEN UP - Set Current co-ord if any arguments}
procedure do_PU_cmd;
var x_int, y_int: integer;
begin
read_or_reset_args(2);
if args then
begin
x_int:= round(x);
y_int:= round(y);
scale(x_int, y_int);
moveTo(x_int, y_int);
end;
pen_down:= false;
end;
{----------------------------------------------------------------------------}
{PD - PEN DOWN - Move to and Draw if a co-ord present }
procedure do_PD_cmd;
var x_int, y_int: integer;
begin
read_or_reset_args(2);
if args then
begin
x_int:= round(x);
y_int:= round(y);
scale(x_int, y_int);
lineto(x_int,y_int);
end;
pen_down:= true;
end;
{-----------------------------------------------------------------------------}
{ PA - POINT ABSOLUTE - Move to x,y, Drawing if PEN DOWN}
procedure do_PA_cmd;
var x_int, y_int: integer;
save_x, save_y : integer;
begin
read_or_reset_args(2);
if args then
begin
x_int:= round(x);
y_int:= round(y);
scale(x_int, y_int);
if pen_down then lineto(x_int,y_int)
else moveto(x_int,y_int);
if symbol_mode then {If symbol-mode then PLOT symbol Char at Destination}
begin
save_x:= getX; save_y:= getY;
outtext(symbol_char);
moveto(save_x, save_y); {Ensure current point doesn't change}
end;
end;
end;
{-----------------------------------------------------------------------------}
{ PR - POINT RELATIVE - Moveto or Draw relative to Last position}
procedure do_PR_cmd;
var x_int, y_int: integer;
save_x, save_y : integer;
begin
read_or_reset_args(2);
if args then
begin
x_int:= round(x);
y_int:= round(y);
scale(x_int, y_int);
x:= getX;
y:= GetY;
if pen_down then lineto(GetX+x_int, GetY+y_int)
else moveto(GetX+x_int, GetY+y_int);
if symbol_mode then {Plot symbol character at endpoint}
begin
save_x:= getX; save_y:= getY;
outtext(symbol_char);
moveto(save_x, save_y);
end;
end;
end;
{-----------------------------------------------------------------------------}
{ LB - LABEL - Output text in current SIze and DIrection}
procedure do_LB_cmd;
begin
lbl:= '';
while ch <> #03 do
begin
lbl:= concat(lbl, ch);
read(inf, ch);
end;
read(inf, ch); {skip past ";"}
outtext(lbl);
end;
{-----------------------------------------------------------------------------}
{ CI - DRAW CIRCLE - centred at current point }
{ This should really take into account the current scaling so you can draw
elipses (I think). At the moment it always draws perfect circles, using the
X size as its Radius
}
procedure do_CI_cmd;
begin
read_or_reset_args(1); { read Radius }
x:= x/(hard_clip_X) * screen_max_X;
circle(getX, getY, round(x));
end;
{-----------------------------------------------------------------------------}
{ IP - Set the Initial Points for use by the SCale command }
{ To display Concatenated Plots in a different colour, it swaps colours, if
available on each IP cmd. This is useful for viewing different layers of
a printed circuit layout
}
procedure do_IP_cmd;
begin
read_or_reset_args(4);
if not args then set_default_P1_P2
else
begin
set_P1_P2(round(x), round(y), round(x1), round(y1));
colour:= colour - 1;
if colour = 0 then colour:= GetMaxColor;
setcolor(colour);
end;
end;
{-----------------------------------------------------------------------------}
{ SC - Define Coordinate Scale }
{ If there are arguments, scale all following coordinates so that the
ranges defined by the SCALE command lies within the PLOT AREA defined
by the IP command coordinates.
If no arguments the revert to using absolute plotter coordinates.
}
procedure do_SC_cmd;
begin
if ch = ';' then args:= false
else
begin {Don't use READ_AND_RESET as args in wrong order (x,x1,y,y1) }
readarg(x); readarg(x1); readarg(y); readarg(y1);
end;
if args = false then use_plotter_units:= true
else
begin {Scale Command - from now on coords will arrive }
x_min:= x; { scaled between Xmin-Xmax, Ymin-max}
y_min:= y;
x_max:= x1;
y_max:= y1;
use_plotter_units:= false;
end;
end;
{-----------------------------------------------------------------------------}
{ IN - INITIALISE - Beep and wait for a keypress}
procedure do_IN_cmd;
begin
set_default_P1_P2;
pen_down:= false;
if initialise_cmd_count > 0 then
begin
write(#7);
pause:= readkey;
end;
initialise_cmd_count:= initialise_cmd_count+1;
end;
{-----------------------------------------------------------------------------}
{ SP - SET PEN - Usually used to change PEN Colour}
procedure do_SP_cmd;
begin
read_or_reset_args(1);
if args then {Display in a different colour if possible}
if trunc(x) in [1..GetMaxColor] then
setcolor(GetMaxColor - round(x) + 1)
else
begin
colour:= colour-1;
if colour = 0 then colour:= GetMaxColor;
SetColor(Colour);
end;
end;
{-----------------------------------------------------------------------------}
{ SI - Define TEXT SIZE in Centimetres, or reset it to the Default size }
procedure do_SI_cmd;
begin
read_or_reset_args(2);
if args = false then set_default_text_size
else
begin
set_text_size(x,y);
{Now to remember for later - for use by DI instruction}
char_width := x;
char_height:= y;
end;
end;
{-----------------------------------------------------------------------------}
{ SR - Set Text Size - Relative to Scaling Points }
{ This bit has only been loosely tested (ie once) }
procedure do_SR_cmd;
var actual_width, actual_height : real; {for SR cmd}
begin
read_or_reset_args(2);
if args = false then set_default_text_size
else
begin
actual_width := x/100 * (x_p2 - x_p1) * 0.0025; {cm}
actual_height:= y/100 * (y_p2 - y_p1) * 0.0025; {cm}
set_text_size(actual_width, actual_height);
{Now to remember for later - for use by DI instruction}
char_width := actual_width;
char_height:= actual_height;
end;
end;
{-----------------------------------------------------------------------------}
{ SM - SYMBOL MODE - Plot a symbol after each plot/move}
procedure do_SM_cmd;
begin
if ch = ';' then symbol_mode:= false
else
begin
symbol_mode:= true;
symbol_char:= ch;
end;
read(inf, ch);
end;
{-----------------------------------------------------------------------------}
{ DI/DR - Set Orientation to display following Text }
{ Ideally we should be able to Rotate the direction of the text
(ie horizontal but upside down, but Turbo's toolbox doesn't handle this
Instead we'll use the SetTextJustify to do it in 90 degree increments
}
procedure do_DI_or_DR_cmd;
begin
read_or_reset_args(2);
if not args then set_Default_Text_direction {set to Defaults}
else
begin
if abs(x) >= abs(y) then {RUN > RISE}
begin
text_Direction:= HorizDir;
if x > 0 then SetTextJustify(LeftText, BottomText) { 0 degrees}
else SetTextJustify(RightText, TopText); {180 degrees}
end
else
begin
text_direction:= VertDir;
if y >= 0 then SetTextJustify(RightText, BottomText) { 90 degrees}
else SetTextJustify(LeftText, TopText); {270 degrees}
end;
{Now call SET_TEXT_SIZE to alter TextDirection, using prev WIDTH&HEIGHT}
set_text_size(char_width, char_height); {Either Default or Set by SI instr}
end;
end;
{-----------------------------------------------------------------------------}
{DF - Default - Reset various parameters to known state }
procedure do_DF_cmd;
begin
set_default_text_direction;
symbol_mode:= false;
use_plotter_units:= true; {Turn off scaling}
end;
{-----------------------------------------------------------------------------}
{ DECODE and EXECUTE the HPGL command in "cmd" }
procedure DECODE_and_EXECUTE_HPGL_COMMAND;
begin
if cmd = 'PU' then do_PU_cmd
else if cmd = 'PD' then do_PD_cmd
else if cmd = 'PA' then do_PA_cmd
else if cmd = 'PR' then do_PR_cmd
else if cmd = 'LB' then do_LB_cmd
else if cmd = 'CI' then do_CI_cmd
else if cmd = 'IP' then do_IP_cmd
else if cmd = 'SC' then do_SC_cmd
else if cmd = 'IN' then do_IN_cmd
else if cmd = 'SP' then do_SP_cmd
else if cmd = 'SI' then do_SI_cmd
else if cmd = 'SR' then do_SR_cmd
else if cmd = 'SM' then do_SM_cmd
else if cmd = 'DF' then do_DF_cmd
else if cmd = 'DI' then do_DI_or_DR_cmd
else if cmd = 'DR' then do_DI_or_DR_cmd
else if cmd = 'VS' then read_or_reset_args(1) {VELOCITY SET (of Pen) - Ignore}
else if cmd = 'ZZ' then {End of file Sentinel - ignore this cmd}
else {UNIMPLEMENTED COMMAND}
if unknown_count = unknown_max then finished:= true {abort}
else
begin {Add Unknown Command to list of unknowns}
unknown_count:= unknown_count+1;
while (ch <> ';') and (not eof(inf)) do
begin
if (length(cmd) < 78) then cmd:= concat(cmd, ch);
read(inf, ch);
end;
unknown_cmds[unknown_count]:= cmd;
end;
end;
{-----------------------------------------------------------------------------}
procedure VIEW_UNKNOWN_COMMANDS;
var i : integer;
ch : char;
begin
clrscr;
if unknown_count = 0 then Writeln('No unimplemented HPGL commands encountered')
else
begin
writeln(' UNIMPLEMENTED HPGL COMMANDS');
writeln;
for i:= 1 to unknown_count do
begin
writeln(unknown_cmds[i]);
if (unknown_count mod 20 ) = 0 then
begin
write('Press any key : '); ch:= readkey;
end;
end;
writeln;
end;
ch:= readkey;
end;
{-----------------------------------------------------------------------------}
procedure Graphics_Error(error: string);
begin
Writeln(error, ': ', GraphErrorMsg(GraphResult));
Halt(1);
end;
procedure REGISTER_GRAPHICS_BITS;
begin
{ Register all the drivers }
if RegisterBGIdriver(@CGADriverProc) < 0 then graphics_error('CGA');
if RegisterBGIdriver(@EGAVGADriverProc) < 0 then graphics_error('EGA/VGA');
if RegisterBGIdriver(@HercDriverProc) < 0 then graphics_error('Herc');
if RegisterBGIdriver(@ATTDriverProc) < 0 then graphics_error('AT&T');
if RegisterBGIdriver(@PC3270DriverProc) < 0 then graphics_error('PC 3270');
{ Register SMALL Font - only one used }
if RegisterBGIfont(@SmallFontProc) < 0 then graphics_error('Small Font');
if auto_detect_graphics then
Graphics_Driver := Detect; { autodetect the hardware }
InitGraph(Graphics_Driver, Graphics_Mode, ''); { activate graphics }
if GraphResult <> grOk then { any errors? }
begin
Writeln('Graphics init error: ', GraphErrorMsg(Graphics_Driver));
Halt(1);
end;
end;
procedure OPTIONS_ERROR (msg : string);
begin
writeln(msg);
writeln('Type ');
writeln(' HPGLVIEW ? ');
writeln('for a list of valid options');
writeln;
halt(1);
end;
{-----------------------------------------------------------------------------}
{SET THE GRAPHICS DRIVER and MODE accordin to the Supplied arguments }
{ Graphics Driver and Mode are set up via a command line option of the form:
/G graphics-driver graphics-mode
Check that the mode is valid for the indicated driver, ABORT if it isn't.
}
procedure MANUAL_GRAPHICS_SETUP (driver_no, mode_no : integer);
var status : integer;
begin
if paramcount < mode_no then options_error ('Must define Graphics Driver & Mode')
else
begin
val(paramstr(driver_no), graphics_driver, status);
if status <> 0 then options_error('Graphics driver must be integer');
if not (graphics_driver in [1..10]) then
options_error(concat('Invalid Graphics Driver : ', paramstr(driver_no)));
val(paramstr(mode_no), graphics_mode, status);
if status <> 0 then
options_error(concat('Graphics mode must be integer : ',paramstr(mode_no)));
{Check the Specified Mode is valid for Defined Driver}
case graphics_driver of
{CGA} 1 :if not (graphics_mode in [0..4]) then options_error('Graphics mode for CGA must be 0..4');
{MCGA} 2 :if not (graphics_mode in [0..5]) then options_error('Graphics mode for MCGA must be 0..5');
{EGA } 3 :if not (graphics_mode in [0..1]) then options_error('Graphics mode for EGA must be 0..1');
{EGA64} 4 :if not (graphics_mode in [0..1]) then options_error('Graphics mode for EGA64 must be 0..1');
{EGAMono} 5 :if not (graphics_mode in [3 ]) then options_error('Graphics mode for EGAMono must be 3');
{IBM8514} 6 :if not (graphics_mode in [0 ]) then options_error('Graphics mode for IBM8514 must be 0');
{HercMono} 7 :if not (graphics_mode in [0 ]) then options_error('Graphics mode for HercMono must be 0');
{ATT400} 8 :if not (graphics_mode in [0..5]) then options_error('Graphics mode for ATT400 must be 0..5');
{VGA} 9 :if not (graphics_mode in [0..2]) then options_error('Graphics mode for VGA must be 0..2');
{PC3270} 10 :if not (graphics_mode in [0 ]) then options_error('Graphics mode for PC3270 must be 0');
end; {case}
end;
end;
procedure display_licence;
begin
clrscr;
writeln(' HPGLVIEW - a on-screen Previewer for HPGL files');
writeln(' Copyright (C) 1991 Giovanni S. Moretti');
writeln('');
writeln(' This program is free software; you can redistribute it and/or modify');
writeln(' it under the terms of the GNU General Public License as published by');
writeln(' the Free Software Foundation; either version 1, or (at your option)');
writeln(' any later version.');
writeln('');
writeln(' This program is distributed in the hope that it will be useful,');
writeln(' but WITHOUT ANY WARRANTY; without even the implied warranty of');
writeln(' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the');
writeln(' GNU General Public License for more details.');
writeln('');
writeln(' You should have received a copy of the GNU General Public License');
writeln(' along with this program; if not, write to the Free Software');
writeln(' Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.');
writeln('-----------------------------------------------------------------------------');
writeln(' Giovanni Moretti | EMAIL: G.Moretti@massey.ac.nz');
writeln(' Computer Centre, Massey University | ');
writeln(' Palmerston North, New Zealand |');
writeln('-----------------------------------------------------------------------------');
writeln('Please send me copies of any major improvements so I can coordinate new');
writeln('versions.');
writeln;
write('Press any key for help screen : '); ch:= readkey;
end;
{-----------------------------------------------------------------------------}
procedure QUICK_HELP;
begin
display_licence;
clrscr;
writeln(' ********* HPGLVIEW v1.0 - A Screen Previewer for HPGL files *********');
writeln('');
writeln('This program will display the contents of an HPGL file, normally intended for');
writeln('a plotter, on the PC''s screen. The screen is treated as an A3 or A4 page and');
writeln('aspect ratio effects are ignored to maximise the available resolution.');
writeln('');
writeln(' HPGLVIEW <filename> [/A3 | /A4 ] [/G graphics-driver graphics-mode ] [/D]');
writeln('');
writeln(' Options : /A3 /A4 - Paper size, /G - Graphics Mode, /D Show unknown HPGL cmds');
writeln(' Defaults: A4 page, Autodetect graphics driver, Ignore unknown cmds');
writeln;
writeln('GRAPHICS DRIVERS AND (VALID MODES): Try mode 0 if unsure.');
writeln('CGA : 1(0-4) CGA : 2(0-5) EGA: 3(0-1) EGA64: 4(0-1) EGAmono: 5(3)');
writeln('IBM8514: 6(0) HercMono: 7(0) ATT400: 8(0-5) VGA: 9(0-2) PC3270: 10(0)');
writeln('');
writeln('Recognised HPGL Commands');
writeln(' PA, PU, PD, PR, LB, CI, VS, SP, IP, SC, SM, SI, DI, IN, DR, SR, DF');
writeln('');
writeln('Plotter Limits: A4 - Plot area 270x190mm, Hard limits X/Y = 10870x 7600');
writeln(' A3 399x271mm 15970x10870');
writeln;
writeln('written by Giovanni Moretti Email: G.Moretti@massey.ac.nz');
writeln;
halt(1);
end;
{----------------------------------------------------------------------------}
{ Decode in execute the command line options (if any ) }
procedure SET_OPTIONS;
var next : integer;
begin
debug:= false;
paper_size:= 4;
auto_detect_graphics:= true;
next:= 2;
while next <= paramcount do
begin
if (paramstr(next) = '/h') or (paramstr(next) = '/H') then quick_help
else
if (paramstr(next) = '/a3') or (paramstr(next) = '/A3') then
paper_size:= 3
else
if (paramstr(next) = '/a4') or (paramstr(next) = '/A4') then
paper_size:= 4
else
if (paramstr(next) = '/d') or (paramstr(next) = '/D') then debug:= true
else
if (paramstr(next) = '/g') or (paramstr(next) = '/G') then
begin
auto_detect_graphics:= false;
manual_graphics_setup(next + 1, next+2);
next:= next+2;
end
else options_error(concat('Unknown Option : ',paramstr(next)));
next:= next+1;
end;
set_paper_size(paper_size);
end; {set_options}
{----------------------------------------------------------------------------}
{ MAINLINE }
begin
digits:= ['0'..'9','.'];
unknown_count := 0;
for i:= 1 to unknown_max do unknown_cmds[i]:= '';
ch:= ' ';
debug:= false;
if paramcount = 0 then quick_help;
filename:= paramstr(1);
if filename[1] in [ '/', '?'] then quick_help;
assign(inf, filename);
{$I-} reset(inf); {$I+}
if ioresult <> 0 then begin writeln('HPGLVIEW: ', filename, ' not found'); halt; end;
{GOT A VALID FILENAME}
set_paper_size(4);
if paramcount > 1 then set_options;
cnt:= 0;
clrscr;
{---------------------------------------------------------------------------}
{ Set up graphics and display Boarder }
register_graphics_bits; {Load appropriate graphics driver and Font }
{ Draw the Border Representing the Printed Page }
screen_max_X:= getMaxX;
screen_max_Y:= getMaxY;
moveto(0,0);
lineto(screen_max_x,0);
lineto(screen_max_x, screen_max_y);
lineto(0, screen_max_y);
lineto(0,0);
{ Display File title at top of page }
SetColor(GetMaxColor);
colour:= GetmaxColor;
SetTextStyle(smallfont,horizdir,6);
SetTextJustify(CenterText,TopText);
OutTextXY(screen_max_x div 2, 0, concat(' *** ', filename, ' *** '));
{----------------------------------------------------------------------------}
{ Set up HPGL Defaults related to Paper Size }
text_direction := horizDir;
use_plotter_units := true; {Can be changed with SCALE command }
symbol_mode := false;
initialise_cmd_count:= 0;
IP_cmd_count := 0;
set_default_P1_P2; {Define initial Scaling Points for this paper size}
set_default_text_direction;
set_default_text_size; {As defined in HPGL manual}
{------------------------------ Main Loop --------------------------------}
finished:= false;
while not eof(inf) and not finished do
begin
if keypressed then {If ESC pressed then abort immediately }
begin
ch:= readkey;
if ch = #$1B {ESC} then finished:= true;
end;
if not finished and not eof(inf) then
begin
get_cmd;
decode_and_execute_HPGL_command;
end;
end;
if not finished then begin write(chr(7)); pause:= readkey; end;
closegraph;
if debug then view_unknown_commands;
end.